package com.chenyue.cm.auth;

import com.chenyue.cm.common.constant.RedisPrefix;
import com.chenyue.cm.exception.SysRuntimeException;
import com.chenyue.cm.user.domain.JdAppUser;
import com.chenyue.cm.utils.RedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * 有@LoginUser注解的方法参数，注入当前登录用户
 *
 * @author chenshun
 * @date 2017-03-23 22:02
 */
@Component
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

    private final RedisUtils redisUtils;

    public LoginUserHandlerMethodArgumentResolver(RedisUtils redisUtils) {
        this.redisUtils = redisUtils;
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(JdAppUser.class)
                && parameter.hasParameterAnnotation(LoginUser.class);
    }

    @Override
    public JdAppUser resolveArgument(MethodParameter parameter, ModelAndViewContainer container, NativeWebRequest request,
                                     WebDataBinderFactory factory) {
        // 获取用户ID
        Object object = request.getAttribute(AuthorizationInterceptor.USER_KEY, RequestAttributes.SCOPE_REQUEST);
        String requestToken = (String) request.getAttribute(AuthorizationInterceptor.TOKEN, RequestAttributes.SCOPE_REQUEST);
        if (object == null) {
            throw new SysRuntimeException("登录失效，请重新登录", HttpStatus.UNAUTHORIZED.value());
        }
        String userId = String.valueOf(object);
        Object user = redisUtils.getRedis(RedisPrefix.LOGIN_USER + userId);
        String currentToken = redisUtils.getToken(userId);
        if (user == null) {
            throw new SysRuntimeException("登录失效，请重新登录", HttpStatus.UNAUTHORIZED.value());
        }
        if (StringUtils.isEmpty(requestToken)) {
            throw new SysRuntimeException("登录失效，请重新登录", HttpStatus.UNAUTHORIZED.value());
        }
        if (StringUtils.isNotBlank(currentToken) && !currentToken.equals(requestToken)) {
            throw new SysRuntimeException("您的账号已经在别处登陆", HttpStatus.UNAUTHORIZED.value());
        }
        // 获取用户信息
        return (JdAppUser) user;
    }
}
